/*jslint vars: true, plusplus: true */
/*global module, Sizzle */
(function () {
	'use strict';

	function lc2Selector($) {
		if (typeof $ === 'undefined') {
			throw new Error('[lc2-sizzle]: Sizzle is not found!');
		}

		function sizzleIframe(iSA, rootContext) {
			// iSA: iframeSelectorArray.

			var parentArray, result = [],
				deepth = 0,
				lastSelector = iSA.pop(),
				maxDeepth = iSA.length,
				iframeContext = [];

			function queryIframe(context) {
				$(iSA[deepth], context).forEach(function (element) {
					if (element.tagName === 'IFRAME') {
						iframeContext.push(element.contentWindow.document);
					}
				});
			}

			// init query by rootContext.
			queryIframe(rootContext);
			deepth += 1;
			// travel.
			while (deepth < maxDeepth && iframeContext.length) {
				parentArray = iframeContext;
				iframeContext = [];
				parentArray.forEach(queryIframe);

				deepth += 1;
			}

			// Query all Element by last deepth context array.
			if (deepth === maxDeepth) {
				iframeContext.forEach(function (parentContext) {
					result = result.concat($(lastSelector, parentContext));
				});
			}

			return result;
		}

		function LC2Sizzle(selector, context) {
			/**
			 * sGroup[ [sIframeContext_1], [sIframeContext_2],... ]
			 */
			var resultArray = [],
				group = selector.split(',');

			group.forEach(function (selector) {
				var gR, iframeContext = selector.split('<');

				if (iframeContext.length < 1) { return; }

				if (iframeContext.length === 1) {
					gR = $(iframeContext[0], context);
				} else {
					gR = sizzleIframe(iframeContext, context);
				}

				gR.forEach(function (element) {
					if (resultArray.indexOf(element) === -1) {
						resultArray.push(element);
					}
				});

			});

			return resultArray;
		}

		return LC2Sizzle;
	}

	//make it available in node.js as well
	if (typeof module !== 'undefined' && module.exports) {
		module.exports = lc2Selector;
	} else {
		window.$ = lc2Selector(Sizzle);
	}
}());
